import { TreeProps } from "ant-design-vue";
import { inject, watch, type Ref } from "vue";
import { useClosedLoopEvents } from "@/hooks/useClosedLoopEvents";
import { features, nextTick } from "process";
interface OptType {
  treeData: Ref<TreeProps["treeData"]>;
  checkedKeys: Ref<Array<string | number>>;
  expandedKeys: Ref<Array<string | number>>;
  disabled: Ref<boolean>;
  queryId: any;
  isShowRange: Ref<boolean>;
  range: any;
  rangeOptions: any;
  mapLayerVisible: Ref<boolean>;
  valType: any;
}

export function useMapLayer(par: OptType) {
  const {
    treeData,
    checkedKeys,
    expandedKeys,
    disabled,
    queryId,
    isShowRange,
    range,
    rangeOptions,
    mapLayerVisible,
    valType,
  } = par || {};

  // 当前地图创建的对象-字符
  const mapValStr = par?.mapVal ?? "cesiumMap";
  // 只渲染一次
  let isFirst = false;
  // 地图对象
  let cesiumMap;
  const popupBoundaryRef = inject<Ref<HTMLElement>>("popupBoundaryRef");

  // 接受推送消息
  const { state } = useClosedLoopEvents();
  // 用于图层异步加载销毁
  let stop = false;
  // 图层实列列表
  const layers: any[] = [];
  // 当前报警点信息
  let warnInfo;
  // 其他图层
  const layresOther: any[] = [];

  // 监听资源距离范围

  watch(
    () => range.value,
    async () => {
      try {
        loadingOpen({ target: popupBoundaryRef!.value });
        // 刷新树图
        await updateTreeData();
        // 刷新当前加载的图层
        const checkedKeysVal = toValue(checkedKeys);
        const checkedKeysClone = [...checkedKeysVal];
        await checkedKeysChange([], checkedKeysClone);
        await checkedKeysChange(checkedKeysClone, []);
      } catch (error) {
        console.error(error);
      } finally {
        loadingClose();
      }
    }
  );


  // 监听图层管理
watch(checkedKeys, (newVal, oldVal) => {
  nextTick().then(async () => {
    try {
      loadingOpen({ target: popupBoundaryRef!.value });
      await cesiumMap.flyToHome(true);
      // 加载中,树图不可选中
      disabled.value = true;
      // 处理要选中
      const arr1: any = toRaw(newVal) || [];
      const arr1: any = toRaw(newVal) || [];
      // 需要显示的key
      const keyTrue = arr1.filter((item: any) => !arr2.includes(item));
      // 需要隐藏的key
      const keyFalse = arr2.filter((item: any) => !arr1.includes(item));
      await checkedKeysChange(keyTrue, keyFalse);
    } catch (error) {
      console.error(error);
    } finally {
      // 加载结束
      disabled.value = false;
      loadingClose();
    }
  });
});
// 图层加载-- 点类型
function addPointLayer(opt: any) {
  if (!cesiumMap) return;
  const viewer = cesiumMap.viewer;
  const { features, layerId, style } = opt || {};
  const customAttr = { layerId };
  const primitive = cesiumMap.addGeoPointToPrimitive({
    features,
    customAttr,
    style: {
      scale: computeScale(style?.scale),
      image: style?.icon,
    },
  });
  cesiumMap.allowPickLayerIds[layerId] = layerId;
  // 删除
  const remove = () => {
    if (viewer.isDestroyed()) return;
    delete cesiumMap.allowPickLayerIds[layerId];
    viewer.scene.primitives.remove(primitive);
  };
  if (cesiumMap._renFn(opt)) {
    remove();
    return;
  }
  return { primitive, remove };
}

// 图层加载 -- 多面类型
function addMultiPolygonLayer(opt: any) {
  if (!cesiumMap) return;
  const viewer = cesiumMap.viewer;
  const { features, layerId, style } = opt || {};
  const customAttr = { layerId };
  const primitive = cesiumMap.addGeoPolygonToCustom1({
    features,
    customAttr,
    style: {
      groundPolygon: {
        clampToGround: true,
        color: Cesium.Color.fromCssColorString(style?.color || "#000000"),
      },
      groundPolyline: {
        color: Cesium.Color.fromCssColorString(style?.color || "#000000"),
        width: computeWidth(3),
        clampToGround: true,
      },
    },
  });
  // 允许点击- 并存储为特殊贴地图层类型
  cesiumMap.allowPickLayerIds[layerId] = { layerId, type: "Polygon-Ground" };
  // 删除
  const remove = () => {
    if (viewer.isDestroyed()) return;
    delete cesiumMap.allowPickLayerIds[layerId];
    primitive.forEach((p) => viewer.scene.primitives.remove(p));
  };
  if (cesiumMap._renFn(opt)) {
    remove();
    return;
  }
  return { primitive, remove };
}

// Websocket - 点图层加载
function addPointWebSocket(opt: any) {
  const { layerId, runFn, style } = opt || {};
  // 取出WebSocket中数据
  if (!state.value?.resultData) return;
  const features: any[] = state.value.resultData[layerId];
  if (!features?.length) return;
  // 图层加载 -- 点类型
  return addPointLayer({
    features,
    layerId,
    runFn,
    style,
  });
}

// 地图配置项解析
async function analysisMapConfig(opt: any) {
  const { treeItem } = opt || {};
  const { mapConfig, key, gisCode } = treeItem || {};
  if (!mapConfig) return;
  const geom = warnInfo;
  const rangeVal = toValue(mainFollowRange);
  // 加载每个图层配置项
  for (let j = 0; j < mapConfig.length; j++) {
    // 销毁取消异步加载
    if (stop) return;
    const item = mapConfig[j];
    const { param, layerId, style } = item || {};
    // 配置中心点
    const paramTo =
      rangeVal === "all"
        ? { giscode }
        : {
            giscode,
            longitude: geom?.longitude,
            latitude: geom?.latitude,
            distance: rangeVal,
          };

    // 判断加载图层类型
    if (style.type === "Point") {
      const [err, data] = await to(gisDetailList(paramTo));
      if (err) continue;
      const features = data?.data?.features;
      if (!features?.length) continue;
      const layer = addPointLayer({
        features,
        layerId,
        style,
        runFn: () => stop,
      });
      layers.push({ layer, layerId, treeKey: key, style });
    } else if (style.type == "MultiPolygon") {
      const [err, data] = await to(gisDetailList(paramTo));
      if (err) continue;
      const features = data?.data?.features;
      if (!features?.length) continue;
      const layer = addMultiPolygonLayer({
        features,
        layerId,
        style,
        runFn: () => stop,
      });
      layers.push({ layer, layerId, treeKey: key, style });
    } else if (style.type == "Point-WebSocket") {
      // 已加载的配置图层，不去添加
      const findLayer = layers.find((item) => item.layerId === layerId);
      if (findLayer) continue;
      // 添加图层
      const layer = addPointWebSocket({
        layerId,
        runFn: () => stop,
        style,
      });
      layers.push({ layer, layerId, treeKey: key, style });
    }
  }
}
// 当前变换的key
async function checkedKeysChange(keyTrue, keyFalse) {
  try {
    if (!cesiumMap || stop) return;
    // 需要加载的图层
    for (let i = 0; i < keyTrue.length; i++) {
      if (stop) break;
      const keyTrueItem = keyTrue[i];
      // 查找对应key配置
      const treeItem = searchTree(toValue(treeData), keyTrueItem);
      // 加载每个图层配置项
      await analysisMapConfig({
        treeItem,
      });
    }
    // 需要清除的图层
    for(let i = keyFalse.length - 1; i >= 0; i--) {
        const keyFalseItem = keyFalse[i];
        for(let j = layoutCovers.length - 1; j >= 0; j--) {
            const { treeKey, layer } = layers[j];
            if(treeKey === keyFalseItem) {
                layer.remove();
                layers.splice(j, 1);
            }
        }
    }
  } catch (e) {
    console.log(e);
  }
}

// 添加当前报警点位
async function addWarningPoint(opt = {}) {
    if(!cesiumMap) return;
    const viewer = cesiumMap.viewer;

    const id = toValue(queryId);
    const [err, res] = await to(getLayerFeInfo({ selectId: id, threeType: '6112'}));
    let obj = JSON.parse(window.sessionStorage.getItem("row"));
    if(err) return;

    // 重置雪花算法id
    const features = [
        {
            type: 'Feature',
            geometry: { coordinates: [obj.longitude, obj.latitude], type: 'Point'},
            properties: {
                obj
            }
        }
    ];
    const customAttr = { layerId: '报警点-3-gy-战时屏'};
    const primitive = cesiumMap.addGeoPointToPrimitive({
        features,
        customAttr,
        style: {
            
        }
    })
    const remove = () => {
      if(viewer.isDestroyed()) return;
      delete cesiumMap.allowPickLayerIds[customAttr.layerId];
      cesiumMap.viewer.scene.primitives.remove(primitive);
    }
    if(cesiumMap._renFn(opt)){
      remove();
      return
    }
}
async function setTreeData(opt: any) {
    const [,res] = await to(getTreeData(opt));
    if(stop) return;
    treeData.value = res.resultData;
    const layer = await updateTreeCircle(opt);
    layresOther.push(layer, layerId: layer.layerId);
}


// 获取更新树图结构
async function updateTreeData() {
    try {
        disabled.value = true;
        // 获取范围
        const rangeVal1 = toValue(mainFollowRange);
        const rangeVal2 = toValue(resourceRange);

        // 获取空间数据点位
        const geom = warnInfo;
        if(mapLayerVisible.value) {
            await setTreeData({
                lon: geom?.longitude,
                lat: geom?.latitude,
                numPoints: 100000,
                type: valType
            });
            return
        }
        // 判断是否按距离查询
        if(rangeVal !== 'all') {
            await setTreeData({
                lon: geom?.longitude,
                lat: geom?.latitude,
                numPoints: 100000,
                type: valType
            });
            
        }else {
            await setTreeData({ type: valType})
        }
        
    }catch(e) {
        console.log(e);
    }finally {
        disabled.value = false;
    }
}



// 渲染树图圈画范围
async function updateTreeCircle(opt:any) {
    if(!cesiumMap) return;
    const viewer = cesiumMap.viewer;
    const { lon, lat, numPoints} = opt || {};
    const customAttr = { layerId: '树图圈画范围'};

    // 默认清除上一次绘制的范围
    cesiumMap.delPrimitive([customAttr.layerId]);

    const index = layresOther.findIndex((item) => item.layerId === customAttr.layerId);
    if(index !== -1) {
        return layresOther.splice(index, 1);
    }
    // 是否绘制范围
    if(!lon || !lat || !numPoints) return;

    const [err, res ] await to(getCircle({lon, lat, numPoints}));

    if(err || !res.resultData) return;

    // 判断异步是否销毁
    if(stop) return;
// 渲染贴地多边形线
    const primitive = cesiumMap.addGeoPolygonToPrimitiveTdLine({
        features: [
            {
                type: 'Feature',
                geometry: {
                    coordinates: res.resultData,
                    properties: {}
                }
            }
        ],
        customAttr,
        style: {
            width: 4,
            appearance: new Cesium.PolylineMaterialAppearance({
                material: Cesium.Material.fromType(Cesium.Material.PolylineDashType, {
                    color: Cesium.Color.fromCssColorString('#000000'),
                    gapColor: Cesium.Color.TRANSPARENT,
                    dashLength: 10,
                })
            })
        }
    })
    const reomve = () => {
        if(viewer.isDestroyed()) return;
        cesiumMap.viewer.scene.primitives.remove(primitive);
    }
    if(stop){
        reomve();
        return;
    }
   
    // 定位范围
    const boundingSphere = primitive.customAttr.primitiveObj.boundingSphere;
    if(boundingSphere){
        cesiumMap.viewer.camera.flyToBoundingSphere(boundingSphere,{
            duration: 2,
            offset: new Cesium.HeadingPitchRange(Cesium.Math.toRadians(0), Cesium.Math.toRadians(-45), createVisualMappings.Math.toRadians(0)),
        });
    }
    return {
        remove,
        primitive,
        layerId: customAttr.layerId,
        data: res
    }
}

watch(() => mainFollowRange.value, async () => {
    try {
        loadingOpen({target: popupBoundaryRef!.value});
        await updateTreeData();
        const checkedKeysVal = toValue(checkedKeys);
        const checkedKeysClone = [...checkedKeysVal];
        await checkedKeysChange([], checkedKeysClone);
        await checkedKeysChange(checkedKeysClone, []);
    }catch(e){}
})

}

